很早就准备写一个字符串系列的面试题,本来已经写好了,大概有十几道题,但是写完才发现,文章好长,连我自己都没有耐心读下去了,索性就将其拆分成几个系列,一来分开后篇幅变小,看起来比较方便。二来也更有针对性,便于精雕细作。比如这篇,在原来的文章中只占很小的篇幅,但是独立出来才发现,东西也不少。既然是第一篇,就来个最最简单的字符串逆序吧。
字符串逆序可以说是最经常考的题目。这是一道入门级的题目,相信80%的程序员经历过这道题。给定一个字符串s,将s中的字符顺序颠倒过来,比如s="abcd",逆序后变成s="dcba"。
普通逆序
基本上没有这么考的,放在这里主要是为了和后面的原地逆序做个对比。很简单,直接分配一个与原字符串等长的字符数组,然后反向拷贝一下即可。
01 |
char *Reverse( char *s) |
02 |
{
|
03 |
//将q指向字符串最后一个字符 |
04 |
char *q = s ; |
05 |
while (*q++) |
06 |
; |
07 |
q -= 2 ; |
08 |
|
09 |
//分配空间,存储逆序后的字符串。 |
10 |
char *p = new char [ sizeof ( char ) * (q - s + 2)] ; |
11 |
char *r = p ; |
12 |
|
13 |
// 逆序存储 |
14 |
while (q >= s) |
15 |
*p++ = *q-- ; |
16 |
*p = '\0' ; |
17 |
|
18 |
return r ; |
19 |
} |
原地逆序
英文叫做in-place reverse。这是最常考的,原地逆序意味着不允额外分配空间,主要有以下几种方法,思想都差不多,就是将字符串两边的字符逐个交换,如下图。给定字符串"abcdef",逆序的过程分别是交换字符a和f,交换字符b和e,交换字符c和d。
设置两个指针,分别指向字符串的头部和尾部,然后交换两个指针所指的字符,并向中间移动指针直到交叉。
01 |
char *Reverse( char *s) |
02 |
{
|
03 |
// p指向字符串头部 |
04 |
char *p = s ; |
05 |
|
06 |
// q指向字符串尾部 |
07 |
char *q = s ; |
08 |
while (*q) |
09 |
++q ; |
10 |
q -- ; |
11 |
|
12 |
// 交换并移动指针,直到p和q交叉 |
13 |
while (q > p) |
14 |
{
|